package com.nimlib;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.LinearLayoutManager;

import com.donkingliang.imageselector.utils.ImageSelector;
import com.jinlejia.erp.R;
import com.jinlejia.erp.databinding.ActivityNimChartP2PBinding;
import com.jinlejia.erp.ui.customer.RecordCustomer1Activity;
import com.jinlejia.erp.ui.new_house.house.DetailNewHouseActivity;
import com.jinlejia.erp.ui.new_house.recommend.CustomerListActivity;
import com.jinlejia.erp.ui.visitor.http.VisitorHttp;
import com.jinlejia.erp.utils.SharePTool;
import com.lab.kit.StringKit;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.Observer;
import com.netease.nimlib.sdk.RequestCallback;
import com.netease.nimlib.sdk.RequestCallbackWrapper;
import com.netease.nimlib.sdk.msg.MessageBuilder;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.MsgServiceObserve;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.AttachmentProgress;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.msg.model.MessageReceipt;
import com.netease.nimlib.sdk.msg.model.QueryDirectionEnum;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import com.netease.nimlib.sdk.uinfo.model.NimUserInfo;
import com.nimlib.adapter.IMChartListAdapter;
import com.nimlib.emoji.IEmoticonSelectedListener;
import com.nimlib.emoji.MoonUtil;
import com.nimlib.msg.HouseInfoMessage;
import com.nimlib.msg.LocalHouseInfoMessage;
import com.nimlib.utils.NimIMUtils;
import com.nimlib.weight.KeyboardListenLayout;
import com.weight.CustomToast;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import kotlin.Unit;

public class NimChartP2PActivity extends AppCompatActivity implements NimIMUtils.SendTextMessageCallBack, NimIMUtils.SendImageMessageCallBack, IMChartListAdapter.OnAdapterEvent, NimIMUtils.SendCustomMessageCallBack, KeyboardListenLayout.OnSizeChangedListener {

    private ActivityNimChartP2PBinding binding;
    private NimUserInfo fromUserInfo;
    private RecentContact contact;

    private String serverAccount;

    /**
     * 打开P2P 聊天页面
     *
     * @param fromUser 最近联系人里的用户信息
     * @param contact  最近会话列表
     */
    public static void start(Context context, NimUserInfo fromUser, RecentContact contact) {
        Intent intent = new Intent();
        intent.setClass(context, NimChartP2PActivity.class);
        intent.putExtra("fromUser", fromUser);
        intent.putExtra("contact", contact);
        context.startActivity(intent);
    }

    public static void start(@NotNull Context context, @NotNull String accountId, @NotNull String houseCode, @NotNull String houseInfo,@NotNull String guestsCode) {
        Intent intent = new Intent();
        intent.setClass(context, NimChartP2PActivity.class);
        intent.putExtra("serverUser", accountId);
        intent.putExtra("houseCode", houseCode);
        intent.putExtra("houseInfo", houseInfo);
        intent.putExtra("guestsCode",guestsCode);
        context.startActivity(intent);
    }

    /**
     * 打开P2P 聊天页面
     *
     * @param serverAccount 用户ID
     */
    public static void start(Context context, String serverAccount) {
        Intent intent = new Intent();
        intent.setClass(context, NimChartP2PActivity.class);
        serverAccount = serverAccount.toLowerCase(); //网易云信聊天ID
        intent.putExtra("serverUser", serverAccount);
        context.startActivity(intent);
    }

    private String houseCode;
    private String houseInfo;
    private String guestsCode;

    private String wxId;
    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_nim_chart_p2_p);
        binding.setEvent(this);
        binding.keyboardLayout.setOnSizeChangedListener(this);
        binding.backBtn.setOnClickListener(v -> finish());
        serverAccount = getIntent().getStringExtra("serverUser");
        houseInfo = getIntent().getStringExtra("houseInfo");
        houseCode = getIntent().getStringExtra("houseCode");
        guestsCode = getIntent().getStringExtra("guestsCode");

        if (TextUtils.isEmpty(serverAccount)) { //如果没有服务器中的ID
            fromUserInfo = (NimUserInfo) getIntent().getSerializableExtra("fromUser");
            contact = (RecentContact) getIntent().getSerializableExtra("contact");
            binding.toolbarTitleTextView.setText(fromUserInfo.getName());
        }

        NimIMUtils.fetchUserInfo(getSessionId(), new RequestCallbackWrapper<List<NimUserInfo>>() {
            @Override
            public void onResult(int code, List<NimUserInfo> result, Throwable exception) {
                if (code == 200 && result.size() == 1) {
                    NimUserInfo info = result.get(0);
                    binding.toolbarTitleTextView.setText(info.getName());
                    wxId = info.getSignature(); //获取用户的签名,个性签名代表用户的微信ID
                }
            }
        });
        loginIM(getSessionId());

        binding.sendButton.setOnClickListener(v -> sendMessage());

        binding.takePhoto.setOnClickListener(v -> takePhoto(false));
        binding.takePhotograph.setOnClickListener(v->takePhoto(true));
        if (TextUtils.isEmpty(binding.editText.getText())) {
            binding.sendButton.setVisibility(View.GONE);
            binding.addButton.setVisibility(View.VISIBLE);
        } else {
            binding.sendButton.setVisibility(View.VISIBLE);
            binding.addButton.setVisibility(View.GONE);
        }
        binding.emojiButton.setOnClickListener(v -> {
            //显示Emoji表情
            showEmojiLayout();
            //滚动到底部
            scrollToBottom();
        });
        binding.addButton.setOnClickListener(v->{

            binding.takePhotoLayout.setVisibility(View.VISIBLE);
            binding.emoticon.setVisibility(View.GONE);
            showTakePhotoLayout();
            //滚动到底部
            scrollToBottom();
        });
        binding.editText.setOnTouchListener((v, event) -> {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                binding.emoticon.setVisibility(View.GONE);
                binding.takePhotoLayout.setVisibility(View.GONE);
            }
            return false;
        });
        binding.editText.addTextChangedListener(new TextWatcher() {
            private int start, count;

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                this.start = start;
                this.count = count;
            }

            @Override
            public void afterTextChanged(Editable s) {
                MoonUtil.replaceEmoticons(NimChartP2PActivity.this, s, start, count);
                if (s.length() == 0) {
                    binding.sendButton.setVisibility(View.GONE);
                    binding.addButton.setVisibility(View.VISIBLE);
                } else {
                    binding.sendButton.setVisibility(View.VISIBLE);
                    binding.addButton.setVisibility(View.GONE);
                }
                String account;
                if (TextUtils.isEmpty(serverAccount)) {
                    account = fromUserInfo.getAccount();
                } else {
                    account = serverAccount;
                }
                NimIMUtils.sendTypingCommand(account);
            }
        });
        registerObservers(true);
    }

    private void closeAll(){
        //关闭键盘
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(binding.editText.getWindowToken(), 0);
        binding.editText.clearFocus();
        binding.editText.requestFocus();
        binding.editText.postDelayed(() -> {
            binding.emoticon.setVisibility(View.GONE);
            binding.takePhotoLayout.setVisibility(View.GONE);
        }, 200);
    }

    private void loginIM(String account){
        SharePTool.UserInfoBean infoBean = SharePTool.getUserInfoBean(this);
        String pin = infoBean.getPin();
        RequestCallback<String> callback = new RequestCallback<String>() {
            @Override
            public void onSuccess(String param) {
                loadIMList(account);
            }

            @Override
            public void onFailed(int code) {

            }

            @Override
            public void onException(Throwable exception) {

            }
        };
        NimIMUtils.login(this,true,pin,callback);
    }

    private void showTakePhotoLayout(){
        //关闭键盘
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(binding.editText.getWindowToken(), 0);
        binding.editText.clearFocus();
        binding.editText.requestFocus();
        binding.editText.postDelayed(() -> {
            binding.emoticon.setVisibility(View.GONE);
            binding.takePhotoLayout.setVisibility(View.VISIBLE);
        }, 200);
    }

    //显示Emoji表情
    private void showEmojiLayout() {
        binding.takePhotoLayout.setVisibility(View.GONE);
        binding.emoticon.setVisibility(View.VISIBLE);
        //关闭键盘
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(binding.editText.getWindowToken(), 0);
        binding.editText.clearFocus();
        binding.editText.requestFocus();
        binding.emoticon.setWithSticker(true);
        binding.emoticon.show(new IEmoticonSelectedListener() {
            @Override
            public void onEmojiSelected(String key) {
                Editable mEditable = binding.editText.getText();
                if (key.equals("/DEL")) {
                    binding.editText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));
                } else {
                    int start = binding.editText.getSelectionStart();
                    int end = binding.editText.getSelectionEnd();
                    start = (start < 0 ? 0 : start);
                    end = (start < 0 ? 0 : end);
                    mEditable.replace(start, end, key);
                }
            }

            @Override
            public void onStickerSelected(String categoryName, String stickerName) {
                System.out.println(categoryName + ":-:" + stickerName);
            }
        });
    }

    private void takePhoto(boolean isCamera){
        ImageSelector.builder()
                .useCamera(isCamera)
                .setMaxSelectCount(10)
                .setViewImage(true)
                .start(this,100);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 100 && resultCode== Activity.RESULT_OK){
            ArrayList<String> list = data.getStringArrayListExtra(ImageSelector.SELECT_RESULT);
            if (list==null)return;
            for (String name:list) {
                NimIMUtils.sendImageMessage(getSessionId(),name,this);
            }
        }
    }

    private void sendMessage() {
        String text = binding.editText.getText().toString();
        if (TextUtils.isEmpty(text)) {
            CustomToast.showToast(this, "请输入文本", 1500);
            return;
        }
        String account = getSessionId();
        NimIMUtils.sendTextMessage(account, text, this);
    }

    //获取会话ID
    private String getSessionId(){
        String account;
        if (TextUtils.isEmpty(serverAccount)){
            account = fromUserInfo.getAccount();
        }else {
            account = serverAccount;
        }
        return account.toLowerCase();
    }

    private IMChartListAdapter adapter;

    @SuppressLint("ClickableViewAccessibility")
    private void loadIMList(String account) {
        NimUserInfo user = NimIMUtils.getLocalUser(this);
        List<IMMessage> emptyResult = new ArrayList<>();

        if (adapter == null) adapter = new IMChartListAdapter(this, user,emptyResult);
        adapter.setAdapterEvent(this);
        binding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
        binding.recyclerView.setAdapter(adapter);
        binding.recyclerView.setOnTouchListener((v, event) -> {
            closeAll();
            return false;
        });
        //从1970年开始计算
        IMMessage anchor = MessageBuilder.createEmptyMessage(account, SessionTypeEnum.P2P, 0);
        NIMClient.getService(MsgService.class).queryMessageListEx(anchor, QueryDirectionEnum.QUERY_NEW, Integer.MAX_VALUE, true).setCallback(new RequestCallbackWrapper<List<IMMessage>>() {
            @Override
            public void onResult(int code, List<IMMessage> result, Throwable exception) {
                if (code == 200) {
                    if (result==null || result.size()==0){
                        NIMClient.getService(MsgService.class).pullMessageHistory(anchor,100,true)
                                .setCallback(new RequestCallbackWrapper<List<IMMessage>>() {
                                    @Override
                                    public void onResult(int code, List<IMMessage> result, Throwable exception) {
                                        if (houseInfo!=null && houseCode !=null){
                                            LocalHouseInfoMessage msg = new LocalHouseInfoMessage();
                                            msg.setAddress(houseInfo);
                                            msg.setCode(houseCode);
                                            IMMessage message = MessageBuilder.createCustomMessage(getSessionId(), SessionTypeEnum.P2P, msg);
                                            result.add(0,message);
                                        }
                                        adapter.setData(result);
                                        scrollToBottom();
                                    }
                                });
                    }else {
                        if (houseInfo!=null && houseCode !=null){
                            LocalHouseInfoMessage msg = new LocalHouseInfoMessage();
                            msg.setAddress(houseInfo);
                            msg.setCode(houseCode);
                            IMMessage message = MessageBuilder.createCustomMessage(getSessionId(), SessionTypeEnum.P2P, msg);
                            result.add(0,message);
                        }
                        adapter.setData(result);
                        scrollToBottom();
                    }
                }
            }
        });
    }

    private boolean isResume = false;

    @Override
    protected void onResume() {
        super.onResume();
        isResume = true;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        registerObservers(false);
    }

    @Override
    protected void onStop() {
        super.onStop();
        isResume = false;
    }

    //region 消息附件上传/下载进度观察者
    private Observer<AttachmentProgress> attachmentProgressObserver = new Observer<AttachmentProgress>() {
        @Override
        public void onEvent(AttachmentProgress progress) {
            int index = getItemIndex(progress.getUuid());
            String sessionId = getSessionId();
            List<IMMessage> items = adapter.getMessageItem();
            if (index >= 0 && index < items.size()) {
                IMMessage item = items.get(index);
                if (TextUtils.equals(item.getFromAccount(),sessionId)){
                    float value = (float) progress.getTransferred() / (float) progress.getTotal();
                    adapter.putProgress(item, value);
                    refreshViewHolderByIndex(index);
                }
            }
        }
    };

    private int getItemIndex(String uuid) {
        List<IMMessage> items = adapter.getMessageItem();
        for (int i = 0; i < items.size(); i++) {
            IMMessage message = items.get(i);
            if (TextUtils.equals(message.getUuid(), uuid)) {
                return i;
            }
        }
        return -1;
    }

    /**
     * 刷新单条消息
     */
    private void refreshViewHolderByIndex(final int index) {
        if (index>0){
            adapter.notifyDataItemChanged(index);
        }
    }
    //endregion

    //region 消息接收观察者
    private Observer<List<IMMessage>> messageObserver = new Observer<List<IMMessage>>() {
        @Override
        public void onEvent(List<IMMessage> imMessages) {
            String sessionId = getSessionId();
            List<IMMessage> messages = new ArrayList<>();
            //当接收到消息时，显示消息，并且滚动到底部
            for (IMMessage message:imMessages) {
                if (TextUtils.equals(message.getFromAccount(),sessionId)){
                    NimIMUtils.sendMessageRe(getSessionId(),message);
                    messages.add(message);
                }
            }
            if (!messages.isEmpty()){
                adapter.addData(messages);
                scrollToBottom();
            }

        }
    };

    //endregion

    private Observer<List<MessageReceipt>> messageReceipt = new Observer<List<MessageReceipt>>() {
        @Override
        public void onEvent(List<MessageReceipt> messageReceipts) {
            System.out.println("ddd");
        }
    };

    private void registerObservers(boolean register) {
        NIMClient.toggleNotification(!register);
        MsgServiceObserve service = NIMClient.getService(MsgServiceObserve.class);
        service.observeReceiveMessage(messageObserver, register);
        service.observeAttachmentProgress(attachmentProgressObserver, register);
        service.observeMessageReceipt(messageReceipt,register);
    }

    private void scrollToBottom() {
        binding.recyclerView.scrollToPosition(adapter.getItemCount() - 1);
    }

    //发送过文本后，滚动到底部
    @Override
    public void onBeforeSendText(IMMessage message) {
        adapter.addData(Collections.singletonList(message));
        scrollToBottom();
    }

    @Override
    public void onSendTextSuccess(IMMessage message) {
        new VisitorHttp().sendWXMessage(getSessionId());
        binding.editText.setText(null);

    }

    @Override
    public void onSendTextFailed(IMMessage message) {

    }

    @Override
    public void onBeforeSendImage(IMMessage message) {
        adapter.addData(Collections.singletonList(message));
        scrollToBottom();
    }

    @Override
    public void onSendImageSuccess(IMMessage message) {
        new VisitorHttp().sendWXMessage(getSessionId());
    }

    @Override
    public void onSendImageFailed(IMMessage message) {

    }

    @Override
    public void onBeforeSendCustomMessage(IMMessage message) {
        adapter.addData(Collections.singletonList(message));
        scrollToBottom();
    }

    @Override
    public void onSendCustomMessageSuccess(IMMessage message) {
        new VisitorHttp().sendWXMessage(getSessionId());
    }

    @Override
    public void onSendCustomMessageFailed(IMMessage message) {

    }

    @Override
    public void onClickPictureItem(ArrayList<ImageViewBean> imgs, int position) {
        NimPictureViewPagerActivity.start(this,imgs,position);
    }

    @Override
    public void onSendHouseInfo(String houseInfo,String houseCode) {
        HouseInfoMessage msg = new HouseInfoMessage();
        HouseInfoMessage.HouseInfo data = new HouseInfoMessage.HouseInfo();
        data.setTitle(houseInfo);
        data.setHouseCode(houseCode);
        data.setSubTitle("Android SubTitle");
        msg.setData(data);
        NimIMUtils.sendHouseInfo(getSessionId(),msg,this);
    }

    @Override
    public void toHouseInfoActivity(String houseCode) {
        DetailNewHouseActivity.start(this,houseCode);
    }

    @Override
    public void toVisitorInfoActivity() {

    }

    //搜索微信
    public void searchWX(View view) {
        try {
            Intent intent = new Intent(Intent.ACTION_MAIN);
            ComponentName cmp = new ComponentName("com.tencent.mm", "com.tencent.mm.ui.LauncherUI");
            intent.addCategory(Intent.CATEGORY_LAUNCHER);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setComponent(cmp);
            startActivity(intent);
        } catch (ActivityNotFoundException e) {
            CustomToast.showToast(this, "检查到您手机没有安装微信，请安装后使用该功能", 1500);
        }
    }




    @Override
    public void onChanged(boolean showKeyboard, int h, int oldh) {
        //int keyboardTop = oldh - (oldh - h); //键盘高度
        if (showKeyboard){ //键盘弹出
            binding.charListLayout.post(this::scrollToBottom);
        }
        //else //键盘关闭
    }
}
